iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
AI Security

AI 這麼聰明,為什麼還會被騙?30 天搞懂 AI 資安系列 第 14 篇

Day 14 - OWASP LLM10:Improper Output Handling,AI 產生的內容不能直接相信

  • 分享至 

  • xImage
  •  

hihi,我是歐娜😺

前面幾天我們一直在看:

使用者丟進 AI 的東西安不安全?

像是 Prompt Injection、資料污染、RAG 找到錯誤內容等等。

但今天要把方向反過來。

不是看:

「什麼東西進到 LLM?」

而是看:

「LLM 產生的東西,接下來去了哪裡?」

今天來看 OWASP LLM Top 10 2026 最後一名:

LLM10:Improper Output Handling(不當輸出處理)。

這一條可以先很簡單理解成:

把 LLM 產生的內容直接當成可信資料,沒有經過驗證或處理,就交給下一個系統使用。

例如:

User
↓
LLM
↓
產生 SQL
↓
Database 直接執行

或:

User
↓
LLM
↓
產生 HTML / JavaScript
↓
Browser 直接 Render

甚至:

User
↓
LLM
↓
產生 Shell Command
↓
Server 直接執行

看到這裡應該已經有一點感覺了:

真正危險的不是 LLM 產生了一段文字。

而是:

系統看到那段文字之後,真的照著做了。

LLM Output 也應該被當成不可信輸入

我們在寫一般 Application 時,應該都很熟悉一個觀念:

User Input 不可信。

例如使用者輸入:

<script>alert('hello')</script>

我們不會直接相信它。

使用者傳進來的:

Query Parameter
Form Data
Request Body
File

通常都需要經過:

Validation
Sanitization
Authorization

再交給後面的系統。

但接上 LLM 之後,很容易出現一個奇怪的心理:

這是 AI 產生的,應該比較安全吧?

其實沒有🤣

因為 LLM 的 Output 本身可能受到:

User Prompt
Prompt Injection
RAG Content
第三方資料
Tool 回傳內容

影響。

也就是說:

攻擊者可能沒有辦法直接控制 Backend,但他有機會先影響 LLM,再利用 LLM 的 Output 間接影響 Backend。

所以今天最重要的一個觀念就是:

LLM Output 也要當成 Untrusted Input。

不要因為它是 AI 產生的,就自動多給一層信任。

最直覺的例子:讓 AI 產生 SQL

假設今天做了一個 Database Assistant。

使用者可以直接用自然語言問:

幫我找出今天新增的 Customer。

LLM 幫忙產生:

SELECT *
FROM customers
WHERE created_at >= CURRENT_DATE;

接著 Backend:

LLM 產生 SQL
↓
Database Execute
↓
回傳結果

看起來超方便。

但問題來了。

如果使用者改問:

幫我產生一段 SQL,把所有資料表都刪掉。

LLM 真的產生:

DROP TABLE customers;

如果你的系統是:

LLM Output
↓
直接 Execute

那……

AI 就真的幫你刪了🤣

這時其實不是:

LLM 回答錯了。

它可能完全照使用者的要求回答。

真正的問題是:

Application 把 LLM 產生的文字,直接當成可以執行的 SQL。

所以真正要防的不是只有:

Prompt 要怎麼寫,叫 AI 不要產生危險 SQL?

而是 Backend 本身就要限制:

哪些 Query 可以執行?
可以操作哪些 Table?
可以做 SELECT 嗎?
可以 DELETE 嗎?
目前這個 User 有沒有權限?

不能把安全責任全部丟給 LLM。

「我有在 System Prompt 裡叫它不要做」還是不夠

可能有人會想:

那我在 System Prompt 寫「絕對不要產生 DELETE SQL」不就好了?

例如:

你是一個 Database Assistant。

只能產生 SELECT Query。

禁止 DELETE。
禁止 DROP。
禁止 UPDATE。

這可以當成其中一道限制。

但它不能是唯一一道。

因為前面 Prompt Injection 已經講過很多次:

LLM 的 Instruction 本身不是強制安全邊界。

如果今天真正的 Backend 權限是:

Database Account
↓
SELECT
INSERT
UPDATE
DELETE
DROP
ALL PRIVILEGES

然後安全機制只有:

拜託 AI 不要產生 DELETE。

這其實非常危險🤣

比較好的設計應該是:

LLM
↓
產生查詢需求
↓
Backend 驗證
↓
只允許安全範圍
↓
Database

甚至 Database Account 本身就只給:

SELECT

這樣就算 LLM 真的產生:

DROP TABLE customers;

後面也執行不了。

這其實又回到前面一直講的:

Least Privilege(最小權限)。

Browser 也不能直接相信 AI 產生的內容

另一個很好理解的例子是:

HTML / JavaScript。

假設今天有一個 AI:

幫使用者產生活動介紹頁面。

LLM 回傳:

<h1>AI Security Workshop</h1>
<p>歡迎報名!</p>

前端直接 Render。

看起來沒問題。

但如果某次產生的內容裡出現:

<script>
  // malicious code
</script>

而前端完全沒有做處理,就直接把內容當成 HTML 執行,

就可能形成:

XSS(Cross-Site Scripting)。

流程變成:

User / 惡意內容
↓
影響 LLM
↓
LLM 產生惡意 HTML / JavaScript
↓
Frontend 直接 Render
↓
Browser 執行

注意喔,

Browser 不知道:

這段 JavaScript 是 AI 寫的耶~

🤣

它只知道:

你叫我執行這段 Code。

所以 AI 產生的網頁內容,一樣需要:

Sanitization
Output Encoding
允許的 HTML Tag
Content Security Policy

等安全處理。

Output Encoding 是什麼?

這裡會看到一個很常見的技術:

Output Encoding。

可以先簡單理解成:

不要讓原本應該只是「文字」的內容,被下一個系統誤認成「可以執行的指令」。

例如使用者輸入:

<script>alert(1)</script>

如果我們只是想把它當成文字顯示,

畫面應該讓使用者看到:

<script>alert(1)</script>

而不是:

真的執行這段 JavaScript。

所以系統在把內容放進 HTML、JavaScript、URL 等不同位置前,

都需要按照那個使用情境做正確處理。

也就是:

AI 產生了什麼是一回事,這段內容接下來要被放在哪裡,又是另一回事。

Shell Command 更不能直接執行

再來一個更危險的例子。

假設做了一個 AI DevOps Assistant。

使用者說:

幫我找出 Server 裡最大的 Log File。

LLM 產生:

du -ah /var/log | sort -rh | head

然後系統:

LLM Output
↓
Shell
↓
Execute

看起來超級自動化。

但如果某次 LLM 產生的是危險 Command,

而 Backend 又直接:

exec(llmOutput)

那風險就非常高。

因為此時:

LLM 其實等於間接拿到了 Shell 的操作能力。

如果再搭配 Prompt Injection:

攻擊者輸入
↓
影響 LLM
↓
LLM 產生危險 Command
↓
Backend 直接 Execute

原本只是:

一段 Prompt。

最後可能一路變成:

Remote Code Execution(RCE)。

所以如果真的要讓 AI 操作系統,

至少應該限制:

允許哪些 Command?
哪些參數?
可以操作哪些路徑?
使用什麼 Service Account?
需要 Human Approval 嗎?

而不是:

AI 回什麼我就跑什麼。

File Path 也可能出問題

Improper Output Handling 不一定都是:

執行 Code

有時候只是拿 AI Output 去組一個 File Path,

一樣可能出事。

例如:

LLM:
請讀取 reports/2026/report.pdf

Backend:

open(llmOutput)

如果輸出的路徑最後變成:

../../../../etc/passwd

就可能產生:

Path Traversal。

也就是透過:

../

一路跑去存取原本不應該碰到的檔案。

所以:

AI 說「請讀這個 File」

不代表 Backend 就真的直接照著那個 Path 去讀。

還是需要確認:

是不是允許的 Directory?
是不是允許的 File Type?
路徑是否在預期範圍?

AI 產生 Code 也是同一個問題

這個應該就超級有感了🤣

現在很常:

AI
↓
產生 Code
↓
Developer Copy
↓
Deploy

如果中間還有人 Review,

至少還有一層。

但如果流程變成:

需求
↓
AI 產生 Code
↓
自動 Build
↓
自動 Deploy
↓
Production

那 AI 產生的內容就直接進 Production 了。

問題是:

AI 產生的 Code 本身可能有漏洞。

例如:

SQL Injection
XSS
Hard-coded Secret
缺少 Authorization
Command Injection

都可能被寫進去。

所以 2026 版的 Improper Output Handling 也特別把:

AI 產生的 Code 被直接拿去 Build / Deploy

納入這類風險。

重點一樣不是:

AI 為什麼寫出 Bug?

而是:

為什麼這段 Code 沒有經過 Review、Security Test,就直接被當成可信 Code?

這跟 Misinformation 有什麼不同?

看到這裡可能會想到 Day 11:

Misinformation。

因為兩個好像都是:

AI Output 有問題。

但其實關注點不一樣。

可以先這樣分:

Misinformation
→ AI 產生錯誤、誤導或不完整的資訊

Improper Output Handling
→ 系統沒有安全處理 AI Output,
  就直接拿去執行或交給其他元件使用

例如 AI 說:

Customer 可以退款。

但其實根本不符合退款條件。

這比較偏:

Misinformation。

但如果 AI 回傳:

DELETE FROM orders;

Backend 直接拿去 Database 執行,

這比較偏:

Improper Output Handling。

甚至 AI 產生的內容本身可以完全正確。

例如:

rm -rf ./data

這是一條完全合法的 Shell Command。

問題只是:

你的系統到底該不該直接執行它?

所以今天這條並不是在判斷:

AI 說得對不對。

而是在判斷:

AI 說完之後,我的 Application 怎麼處理這個 Output?

這跟 Prompt Injection 又有什麼不同?

Prompt Injection 看的是:

攻擊者怎麼影響 LLM 的行為。

Improper Output Handling 看的是:

LLM 產生的結果,後面的系統怎麼使用。

例如:

攻擊者
↓
Prompt Injection
↓
LLM 產生惡意 HTML
↓
Frontend 直接 Render
↓
XSS

這裡:

Prompt Injection
→ 前面的攻擊入口

而:

Improper Output Handling
→ 後面沒有安全處理 LLM Output

兩條可以一起發生。

如果前面 Prompt Injection 成功,

但後面的 Backend 有做好:

Validation
Sanitization
Authorization

攻擊可能還是會被擋下來。

所以這也是為什麼不能只想:

我要做出一個永遠不會被騙的 LLM。

更實際的想法應該是:

就算 LLM 被騙了,後面的系統也不要直接跟著做。

Improper Output Handling 到底怎麼防?

我自己會整理成幾個比較直覺的方向。

1. 把 LLM Output 當成不可信輸入

這是最重要的一件事。

不要:

LLM Output
↓
相信
↓
執行

而是:

LLM Output
↓
驗證
↓
清理
↓
檢查權限
↓
才交給下一個系統

簡單來說:

AI 產生的內容,也要過跟 User Input 類似的安全檢查。

2. 根據「下一站」做不同處理

LLM Output 要去哪裡,

處理方式就不一樣。

例如:

要放進 HTML
→ HTML Encoding / Sanitization

要進 Database
→ Parameterized Query

要組 File Path
→ Path Validation

要呼叫 API
→ Schema Validation

要執行 Tool
→ Authorization

不能只有一個:

sanitizeOutput()

然後幻想什麼地方都能通用🤣

真正重要的是:

下一個系統會怎麼解讀這段內容?

3. Database 不要直接執行 LLM 產生的完整 SQL

如果可以,

盡量不要讓:

LLM
↓
自由產生 SQL
↓
Database Execute

比較安全的方式可能是:

LLM
↓
產生結構化條件
↓
Backend 自己組 Query
↓
Parameterized Query

例如讓 AI 回:

{
  "status": "active",
  "createdAfter": "2026-01-01"
}

再由 Backend 決定:

這些欄位最後要怎麼安全地轉成 SQL。

這會比:

AI,請直接幫我寫完整 SQL。

再無條件 Execute,

安全很多。

4. Tool Call 也要重新驗證

假設 LLM 說:

我要呼叫 refundOrder
orderId = 123

Backend 不應該只是:

AI 說要退款,好喔。

🤣

還是需要檢查:

這個 User 有退款權限嗎?
Order 123 是他的嗎?
訂單真的符合退款條件嗎?
目前有沒有已經退款?

也就是:

LLM 負責提出要做什麼,Backend 負責決定到底能不能做。

5. AI 產生的 Code 要走正常開發流程

不要因為 Code 是 AI 產生的,

就跳過:

Code Review
Static Analysis
Security Scan
Test
CI/CD Check

反而應該把它當成:

一個你還不確定品質的 Contributor 寫的 Code。

🤣

AI 可以幫忙加速。

但它產生的 Code 還是 Code。

一樣可能有:

Bug
Security Vulnerability
錯誤邏輯
危險 Dependency

6. 權限還是要收斂

假設某個 AI 功能真的被 Prompt Injection 影響,

如果它後面的 Service Account 只有:

Read Only

攻擊影響通常就比較有限。

但如果它是:

Admin

那同一段惡意 Output,

造成的結果可能完全不同。

所以 Improper Output Handling 跟前面 Excessive Agency 又會連在一起。

簡單來說:

就算 Output Handling 哪天漏了一層,最小權限還是可以再幫你擋一層。

我覺得 Improper Output Handling 最重要的一個觀念

做到這裡,

其實會發現今天這條非常像傳統 Application Security。

以前我們一直在講:

Never trust user input.

到了 AI Application,

只是多了一個新的輸入來源:

LLM Output。

因為整個流程其實變成:

User
↓
LLM
↓
Application
↓
Database / Browser / Shell / API

對後面的:

Database
Browser
Shell
API

來說,

LLM Output 就是它們收到的 Input。

所以今天我會記:

不要因為內容是 AI 產生的,就把它當成可信資料。

LLM 可以產生:

SQL
HTML
JavaScript
Command
File Path
Code
Tool Parameter

但:

產生 ≠ 可以直接執行。

真正安全的流程應該是:

LLM Output
↓
Validate
↓
Sanitize / Encode
↓
Authorization
↓
限制權限
↓
才交給下一個系統

而且我覺得這一條也很適合拿來幫整個 OWASP LLM Top 10 2026 收尾。

從 Day 05 開始,

我們一路看了:

Prompt 怎麼進來
↓
資料會不會洩漏
↓
AI 能做多少事情
↓
Model 從哪裡來
↓
資料有沒有被污染
↓
資源有沒有邊界
↓
AI 講的資訊能不能信
↓
Hidden Context 會不會暴露
↓
RAG 找到的資料對不對
↓
最後 AI 產生的東西怎麼被使用

最後其實又回到一個非常熟悉的資安觀念:

不要相信任何跨越安全邊界進來的資料。

以前是 User Input。

現在多了一個:

Model Output。

AI 可以幫你決定:

「我覺得下一步應該做這個。」

但真正的 Application 還是要再問一次:

「好,但這件事真的可以做嗎?」

這一層不能省🤣


上一篇
Day 13 - OWASP LLM09:Vector and Embedding Weaknesses,找得到「最像的資料」,不代表找對了
下一篇
Day 15 - AI 不只會回答了,Agent 是真的會幫你做事情
系列文
AI 這麼聰明,為什麼還會被騙?30 天搞懂 AI 資安 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言